package com.leadership.api.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.http.annotation.Rao;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.JsonUtils;
import com.leadership.api.dao.CourseDao;
import com.leadership.api.dao.CourseLearningDao;
import com.leadership.api.dao.UserDao;
import com.leadership.api.dao.UserProjectDao;
import com.leadership.api.entity.CourseLearningMapper;
import com.leadership.api.handler.UMUHandler;
import com.leadership.api.rao.CourseTraineeStatsRao;
import com.leadership.api.service.CourseLearningService;
import com.leadership.entity.Constant;
import com.leadership.entity.course.LdCourse;
import com.leadership.entity.course.CourseLearning;
import com.leadership.entity.project.UserProject;
import com.leadership.entity.umu.UMUExamData;
import com.leadership.entity.user.User;

/**
 * @author haiyan_xiao
 *
 */
@Service("courseLearningService")
public class CourseLearningServiceImpl implements CourseLearningService {
    
    private static final Logger logger = LoggerFactory.getLogger(CourseLearningServiceImpl.class);

    @Dao
    private CourseDao courseDao;

    @Dao
    private CourseLearningDao courseLearningDao;

    @Dao
    private UserDao userDao;

    @Dao
    private UserProjectDao userProjectDao;

    @Autowired
    private UMUHandler umuHandler;
    
    @Rao
    private CourseTraineeStatsRao courseTraineeStatsRao;
    
    @Value("#{config['admin.host']}")
    private String host;

    @Autowired
    private GenericDaoSupport genericDaoSupport;

    /* (non-Javadoc)
     * @see com.leadership.scheduler.service.CourseLearningService#updateCourseLearning()
     */
    public void updateCourseLearning() {
        
        this.updateUmuCourseLearning();
    }
    
    /**
     * 
     */
    private void updateUmuCourseLearning() {
        
        List<LdCourse> courses = courseDao.listUmu();
        
        for(LdCourse course : courses) {
            
            String elements[] = course.getElementId().split(",");
            logger.info("current elementId is [{}]", course.getElementId());
            List<UMUExamData> allUMUExamDatas = new ArrayList<UMUExamData>();
            int elementSize = elements.length;
            
            for(String element: elements) {
                List<UMUExamData> umuExamDatas = umuHandler.listExamData(element);
//                logger.info("get umuExamData [{}]", JsonUtils.toJson(umuExamDatas));
                allUMUExamDatas.addAll(umuExamDatas);
            }
            
//            logger.info("get all umuExamData [{}]", JsonUtils.toJson(allUMUExamDatas));
            
            if(org.apache.commons.collections.CollectionUtils.isNotEmpty(allUMUExamDatas)) {
                Map<String, List<UMUExamData>> allUMUExamDataMaps = CollectionUtils.constructMapValues(allUMUExamDatas, "user.email");
                
                for(String email: allUMUExamDataMaps.keySet()) {
                    
                    List<UMUExamData> userCourseExamDatas = allUMUExamDataMaps.get(email);
                    if(userCourseExamDatas.size() ==  elementSize) {
                        int passCount = 0;
                        Float avgScore = (float) 0;
                        for(UMUExamData umuExamData : userCourseExamDatas) {
                            if(umuExamData.isHasPassed()) {
                                passCount++;
                                avgScore=avgScore + Float.valueOf(umuExamData.getScore());
                            }
                        }
                        if(passCount == elementSize) {
                            Integer grade = (int) (avgScore/elementSize);
                            User user = userDao.load(email);
                            if(user != null) {
                                CourseLearning courseLearning = courseLearningDao.load(email, course, user.getCurrentProjectId());
                                if(courseLearning != null) {
                                    genericDaoSupport.update(courseLearning.update(true, grade));
                                    
                                    UserProject userProject = userProjectDao.load(user, user.getCurrentProjectId());
                                    if(userProject != null) {
                                      if(course.getId().equals(Constant.REQUIRED_COURSE_ONE_ID)) {
                                          userProject.setRequiredCourseOneCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.REQUIRED_COURSE_TWO_ID)) {
                                          userProject.setRequiredCourseTwoCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.REQUIRED_COURSE_THREE_ID)) {
                                          userProject.setRequiredCourseThreeCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.REQUIRED_COURSE_FOUR_ID)) {
                                          userProject.setRequiredCourseFourCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.OPTIONAL_COURSE_ONE_ID)) {
                                          userProject.setOptionalCourseOneCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.OPTIONAL_COURSE_TWO_ID)) {
                                          userProject.setOptionalCourseTwoCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.OPTIONAL_COURSE_THREE_ID)) {
                                          userProject.setOptionalCourseThreeCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.OPTIONAL_COURSE_FOUR_ID)) {
                                          userProject.setOptionalCourseFourCompleted(true);
                                          genericDaoSupport.update(userProject);
                                      } else if(course.getId().equals(Constant.OPTIONAL_COURSE_FIVE_ID)) {
                                          userProject.setOptionalCourseFiveCompleted(true);
                                      }
                                  }
                                }
                            }
                        }
                    }
                }
                
            }
        }
    }
    
    /*
     * (non-Javadoc)
     * @see com.leadership.api.service.CourseLearningService#updateCourseLearningStatus()
     */
    @SuppressWarnings("unchecked")
    public void updateCourseLearningStatus() {
        
        // get training course
        List<LdCourse> courses = courseDao.listTraining();
        List<String> trainingCourseIds = CollectionUtils.extractPropertyList(courses, "trainingCourse");
        
        // get training course's learning
        List<CourseLearning> courseLearnings = courseLearningDao.list(courses);
        Map<String, List<CourseLearning>> courseLearningsMap = CollectionUtils.constructMapValues(courseLearnings, "email");
        List<String> emails = new ArrayList<String>();
        emails.addAll(courseLearningsMap.keySet());
        
        // get traing course data
        String url = host + "/api/course-trainee-stats";
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("emails", emails);
        params.put("courseIds", trainingCourseIds);
        
        HttpResult httpResult = courseTraineeStatsRao.corpCourseTraineeStat(url, params);
        
        // 解析结果，更新 course learning
        String responseString = JsonUtils.toJson(httpResult.getData().get("courseTraineeStatMaps"));
        List<CourseLearningMapper> courseLearningMappers = JsonUtils.parseAsList(responseString, CourseLearningMapper.class);
//        logger.info("get real mappers [{}]", JsonUtils.toJson(courseLearningMappers));
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(courseLearningMappers)) {
            Map<String, List<CourseLearningMapper>> courseLearningMap = com.demo2do.core.utils.CollectionUtils.constructMapValues(courseLearningMappers, "email");
            Map<String, Map<String, CourseLearningMapper>> result = new HashMap<String, Map<String, CourseLearningMapper>>();
            for(String key : courseLearningMap.keySet()) {
                List<CourseLearningMapper> item = courseLearningMap.get(key);
                Map<String, CourseLearningMapper> itemMap = com.demo2do.core.utils.CollectionUtils.constructMapValue(item, "courseId");
                result.put(key, itemMap);
            }
            
//            logger.info("get real courseLearningMap [{}]", JsonUtils.toJson(courseLearningMap));
//            logger.info("get real result [{}]", JsonUtils.toJson(result));
//            logger.info("get real courseLearnings [{}]", JsonUtils.toJson(courseLearnings));
            
            for(CourseLearning courseLearning : courseLearnings) {
                logger.info("email [{}]", courseLearning.getEmail());
                logger.info("training course [{}]", courseLearning.getCourse().getTrainingCourse());
                if(result.get(courseLearning.getEmail()) != null){
                    CourseLearningMapper courseLearningMapper = result.get(courseLearning.getEmail()).get(courseLearning.getCourse().getTrainingCourse());
                    if (courseLearningMapper != null) {
                        genericDaoSupport.update(courseLearning.update(true, courseLearningMapper.getCount()));
                    }
                }
                
                
                
            }
        }
    }
}
